package _a;
import java.io.File;
import java.util.Collections;
import java.util.List;
import mathy.c.Ca;
import mathy.wili.al.antlr.java8.coda.AppName;
import mathy.wili.c.Misc9;
import mathy.wili.c.asm.Asm9;
import mathy.wili.extract_srcFile.java.AsmItemList;
import mathy.wili.extract_srcFile.java.ClsRange;
import mathy.wili.extract_srcFile.java.CodeExtract;
import mathy.wili.extract_srcFile.java.Coms26;
import mathy.wili.extract_srcFile.java.Cont26;
import mathy.wili.extract_srcFile.java.MethodRange;
import mathy.wili.extract_srcFile.java.Visit26;
import net.bytebuddy.jar.asm.MethodVisitor;
/**
 * 
 * @author weila 2021年2月17日
 */
public class CodeExtract_start {
	static {
		Ca.warn(1, "Author: weilai2@163.com, wechat: weilai345");
		Cont26.useAsmOnly.toString();
	}

	static File toSrcRoot;

	static File[] srcRoots;
	public static void startExtractFromClass(Class<?> fromClass) {
		AppName.setApp_collectCode();
		AsmItemList toList = Cont26.toList;
		{//在方法中查找：属性|方法|类型，不断地深入查找
			Ca.logStep("Start from class " + fromClass.getSimpleName() + ", deep visit every fields and methods...");
			Asm9.findInMethod_forCalledMethods_and_fields(//
					fromClass, null, null, Config26.Class_filter, toList);
			Asm9.findInInit_forCalledMethods_and_fields(//
					fromClass, 3, null, Config26.Class_filter, toList);
			toList.deepVisit(1);
		}
		//重要：某些Jar中接口的实现类需要全面深入提取
		if ("".isEmpty()) {
			Ca.logStep("Vist these inerface's implementation...");
			Cont26.visitedClsSet.contains(MethodVisitor.class);
			for (Class<?> superCls : Config26.ClsSet_whichSubClsTobeFullyVisited) {
				if (superCls.equals(MethodVisitor.class))
					Ca.pause();
				List<Class<?>> lis = Cont26.IMP_clsMap.get(superCls);
				if (lis == null)
					continue;
				for (int i = 0; i < Config26.MaxImpleClassNum && i < lis.size(); i++) {
					Class<?> implCls = lis.get(i);
					Asm9.findInMethod_forCalledMethods_and_fields(//
							implCls, null, null, Config26.Class_filter, toList);
					Asm9.findInInit_forCalledMethods_and_fields(//
							implCls, 3, null, Config26.Class_filter, toList);
					toList.deepVisit(1);
				}
			}
		}
		{//确保提取接口的实现方法并深入访问之：如果抽象方法被访问，就得确保其子类实现该方法并深入访问之。
			if ("".isEmpty()) {
				Ca.logStep("If visit absract method, assure it's implementation be visited.");
				for (Class<?> cls : Cont26.visitedClsSet) {
					if (cls.getSimpleName().equals("PutFieldFilter"))
						Ca.pause();
					Coms26.findImpleMethodInClass_and_deepIntoMethod(cls, toList);
				}
			}
		}
		CodeExtract.saveToFile();
		{
			Ca.logStep("Visit TobeExtracted_methods. clsNum:" + Cont26.visitedClsSet.size());
			for (Class<?> cls : Cont26.visitedClsSet) {
				if (cls.getSimpleName().equals("ClsMemberRange"))
					Ca.pause();
				ClsRange cRange = ClsRange.clsRangeOf(cls);
				if (cRange == null)
					continue;
				for (String name : Config26.TobeExtracted_methods.map.keySet()) {
					Class<?>[] cc = Config26.TobeExtracted_methods.map.get(name);
					MethodRange mr = cRange.getMethodRange(name, cc);
					if (mr == null)
						continue;
					if (mr.visited)
						if (Boolean.FALSE)//其内部仍可能有引用缺失
							continue;
					Visit26.visitMethodAndItsContent(mr.cls, mr.get());
				}
			}
		}
		//
		File toSrcRoot = Cont26.getToSrcRoot();
		Coms26.writeVisitedClassMemberToDirectory(toSrcRoot);
		int num = Cont26.JarFileList.size();
		String st = Misc9.strOfList(Cont26.JarFileList, "\n\t");
		Ca.warn(1, "被抽取出的代码需要引入" + num + "个jar包" + (num == 0 ? "。" : "：" + st));
		{
			Ca.debug(1, "----------Ex9.msgList:");
			Collections.sort(Coms26.msgList);
			if (Ca.useLog.canDebug())
				Misc9.printList(Coms26.msgList, 1);
			Ca.debug(1, "----------Ex9.msgList:end.");
			Ca.info(1, "ExtractStart: files extracted.");
		}
		Cont26.INST.print();
		Ca.warn(1, "Extract successfully.\n\n");
	}

	public static void main(String[] args) {
		startExtractFromClass(Config26.getStartClass());
	}
	static int inc;
}